using System;
using Moq;
using NUnit.Framework;
using Tycho.Grammar;
using Tycho.Parser.Peg;

namespace Tycho.UnitTests.Grammar {
    [TestFixture]
    public class NonTerminalCompilerSpecification {
        [Test]
        public void ShouldCompileNonTerminal () {
            var ruleCaptures = new RuleCaptures ();
            var ruleTerm = new FakeTerm ();

            var ruleCompiler = new Mock<INonTerminalRuleCompiler> ();
            ruleCompiler.Setup (r => r.Compile (ruleTerm, It.IsAny<ProductionCompilerContext> ()))
                .Returns (ruleCaptures);

            var nonTerminalBuilder = new Mock<INonTerminalBuilder> ();

            var compiler = new NonTerminalCompiler (ruleCompiler.Object, nonTerminalBuilder.Object);

            var term = new CompositeTerm ("non-terminal", null);
            var name = "non-terminal-name";
            term.SubTerms ["name"] = new IdentifierTerm (name, null);
            term.SubTerms ["rule"] = ruleTerm;

            var deferredCompilations = new DeferredCompilations ();
            var precedence = new ChoicePrecedence (null, 0);
            IProduction production = compiler.Compile (term, precedence, new ProductionCompilerContext (null, null, null, deferredCompilations)).Production;
            deferredCompilations.RunCompilationSteps ();

            var nt = production as NonTerminal;

            Assert.That (nt, Is.Not.Null);
            nonTerminalBuilder.Verify (n => n.Build (name, nt, ruleCaptures));
        }

        class FakeTerm : Term {
            public FakeTerm () : base (null) {
            }
        }
    }
}
